;(function($){
	
	var tabable = function(config) {
		config = config || {};
		
		defaults = tabable.defaultConfig;
		
		// 合并默认配置
	    for (var i in defaults) {
	        if (config[i] === undefined) {
	            config[i] = defaults[i];
	        };
	    };
		
		return new tabable.fn.constructor(config);
	}
	
	tabable.fn = tabable.prototype = {
		constructor: function (config) {
			this.config = config;
			this.triggers = $(config.triggers);
			this.contents = $(config.contents);
			this._loadedAjaxContents = new Array;
			this.init();
		},
	
		init: function() {
			var config = this.config,
				triggers = this.triggers,
				contents = this.contents,
				indexName = config.indexName,
				hoverClass = config.hoverClass,
				self = this;
			
			for(i=0; i<triggers.length; ++i) {
				$(triggers[i]).attr(indexName, i);
				$(contents[i]).attr(indexName, i);
			}
			triggers.click(function(event) {
				$ele = $(this);
				triggers.removeClass(hoverClass);
				$ele.addClass(hoverClass);
				self._showContent($ele);
			});
			
			$(triggers[0]).click();
		},
		
		_findContent: function(trigger) {
			var indexName = this.config.indexName,
				contents = this.contents,
				index = trigger.attr(indexName),
				foundContent = null;
			for(i=0; i<contents.length; ++i) {
				$ele = $(contents[i]);
				currentIndex = $ele.attr(indexName);
				if(currentIndex == index) {
					foundContent = $ele;
					break;
				}
			}
			if(foundContent) {
				contentEle = foundContent;
			} else {
				contentEle = this._copyContentElement(index);
			}
			return contentEle;
		},
		
		_copyContentElement: function(index) {
			var contents = this.contents;
			srcContent = $(contents[0]);
			contentEle = srcContent.clone();
			contentEle.attr(this.config.indexName, index);
			id = 'element'+new Date().getTime();
			contentEle.attr('id', id);
			contentEle.html('');
			srcContent.after(contentEle);
			this._addContentElement(contentEle);
			return contentEle;
		},
		
		_addContentElement: function(contentEle) {
			var contents = this.contents,
				indexName = this.config.indexName;
			arr = new Array(contents.length+1);
			for(i=0; i<contents.length; ++i) {
				arr[i] = contents.get(i);
			}
			arr[i] = contentEle.get(0);
			this.contents = $(arr);
		},
		
		_showContent: function(trigger) {
			var config = this.config,
				index = trigger.attr(config.indexName),
				_loadedContents = this._loadedContents,
				_loadedAjaxContents = this._loadedAjaxContents;
			
			this.contents.hide();
			contentEle = this._findContent(trigger);
			url = trigger.attr('url');
			if(url && _loadedAjaxContents[index] != 'loaded') {
				this._loadAjaxContent(url, contentEle, index);
			}
			contentEle.show();
		},
		
		_loadAjaxContent: function(url, contentEle, index) {
			var method = contentEle.attr('method') ? contentEle.attr('method') : 'GET',
				_loadedAjaxContents = this._loadedAjaxContents,
				target = contentEle,
				loadingClass = this.config.loadingClass;
			
			if(_loadedAjaxContents[index]) return;
			
			if(this.config.clearHistoryOnload) contentEle.html('');
			
			_loadedAjaxContents[index] = 'loading';
			contentEle.addClass(loadingClass);
			
			$.ajax({
				type: method,
				url: url,
				dataType: "html",
				success: function(result) {
					target.html(result);
					_loadedAjaxContents[index] = 'loaded';
					contentEle.removeClass(loadingClass);
				}
			});
		}
		
	}
	
	tabable.fn.constructor.prototype = tabable.fn;
	$.tabable = function(config) {
		return tabable(config);
	} 
	
	tabable.defaultConfig = {
		indexName: 'index',
		hoverClass: 'hover',
		loadingClass: 'loading',
		clearHistoryOnload: false
	}
})(jQuery);